//
// Created by Cammy on 2024/5/12.
//

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>

typedef struct Position {
    int row;
    int col;
} PT;

//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------

typedef PT STDataType;

typedef struct ST {
    STDataType *arr;
    int top;
    int capacity;
} ST;

void STInit(ST *ps);

void STDestroy(ST *ps);

void STBuyCapacity(ST *ps);

// 压栈
void STPush(ST *ps, STDataType x);

// 出栈
void STPop(ST *ps);

STDataType STTop(ST *ps);

int STSize(ST *ps);

bool STEmpty(ST *ps);

void StackCopy(ST *p1, ST *p2);

void STInit(ST *ps) {
    ps->arr = (STDataType *) malloc(sizeof(STDataType) * 4);
    if (ps->arr == NULL) {
        printf("malloc fail...\n");
        exit(-1);
    }
    ps->capacity = 4;
//    ps->top = -1; // 意味着top指向栈顶元素
    ps->top = 0; // 意味着top指向的是栈顶元素的下一个
}

void STDestroy(ST *ps) {
    assert(ps);
    free(ps->arr);
    ps->arr = NULL;
    ps->top = ps->capacity = 0;
}

void STBuyCapacity(ST *ps) {
    STDataType *tmp = realloc(ps->arr, ps->capacity * 2 * sizeof(STDataType));
    if (tmp == NULL) {
        printf("realloc fail...\n");
        exit(-1);
    }

    ps->arr = tmp;
    ps->capacity *= 2;
}

// 压栈
void STPush(ST *ps, STDataType x) {
    assert(ps);

    // 满了就增容
    if (ps->top == ps->capacity) {
        STBuyCapacity(ps);
    }

    ps->arr[ps->top] = x;
    ps->top++;

}

// 出栈
void STPop(ST *ps) {
    assert(ps);
    // 栈空了调用Pop直接报错终止
    assert(ps->top > 0);

    ps->top--;
}

STDataType STTop(ST *ps) {
    assert(ps);
    // 栈空了调用Top直接报错终止
    assert(ps->top > 0);

    return ps->arr[ps->top - 1];
}

int STSize(ST *ps) {
    assert(ps);

    return ps->top;
}

bool STEmpty(ST *ps) {
    assert(ps);

    return ps->top == 0;
}

void STCopy(ST *p1, ST *p2) {
    p2->arr = (STDataType *) malloc(sizeof(STDataType*) * p1->capacity);
    memcpy(p2->arr, p1->arr, sizeof(STDataType) * p1->top);
    p2->top = p1->top;
    p2->capacity = p1->capacity;
}

//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------

// 定义全局变量
ST path;
ST minpath;

void PrintMaze(int **maze, int N, int M) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            printf("%d ", maze[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

// 输出栈里面的坐标路径
void PrintPath(ST *ps) {
    ST rPath;
    STInit(&rPath);

    // 把path的数据倒入rPath
    while (!STEmpty(ps)) {
        STPush(&rPath, STTop(ps));
        STPop(ps);
    }

    while (STSize(&rPath) > 1) {
        PT top = STTop(&rPath);
        printf("[%d,%d],", top.row, top.col);
        STPop(&rPath);
    }

    PT top = STTop(&rPath);
    printf("[%d,%d]", top.row, top.col);
    STPop(&rPath);

    STDestroy(&rPath);
}

bool IsPass(int **maze, int N, int M, PT pos) {
    if (pos.row >= 0 && pos.row < N
        && pos.col >= 0 && pos.col < M
        && maze[pos.row][pos.col] == 1)
        return true;
    return false;

}

void GetMazePath(int **maze, int N, int M, PT cur, int P) {
    // 入栈
    STPush(&path, cur);

    //如果走到出口
    if (cur.row == 0 && cur.col == M - 1) {
        // 找到了更短的路径，更新minpath
        if (P >= 0 && STEmpty(&minpath)
            || STSize(&path) < STSize(&minpath)) {
            // 这里需要用到深拷贝
            STDestroy(&minpath);
            STCopy(&path, &minpath);
        }
    }

    // 探测cur位置的上下左右四个方向
    PT next;
    maze[cur.row][cur.col] = 2;

    // 上
    next = cur;
    next.row -= 1;
    if (IsPass(maze, N, M, next)) {
        GetMazePath(maze, N, M, next, P - 3);
    }

    // 下
    next = cur;
    next.row += 1;
    if (IsPass(maze, N, M, next)) {
        GetMazePath(maze, N, M, next, P);
    }

    // 左
    next = cur;
    next.col -= 1;
    if (IsPass(maze, N, M, next)) {
        GetMazePath(maze, N, M, next, P - 1);
    }

    // 右
    next = cur;
    next.col += 1;
    if (IsPass(maze, N, M, next)) {
        GetMazePath(maze, N, M, next, P - 1);
    }

    // 恢复
    maze[cur.row][cur.col] = 1;

    // 出栈
    STPop(&path);

}

int main() {
    int N = 0, M = 0, P = 0;
    while (scanf("%d %d %d", &N, &M, &P) != EOF) {

        // 动态开辟二维数组
        int **maze = (int **) malloc(sizeof(int *) * N);
        for (int i = 0; i < N; i++) {
            maze[i] = (int *) malloc(sizeof(int) * M);
        }

        // 二维数组的输入
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                scanf("%d", &maze[i][j]);
            }
        }
        STInit(&path);
        STInit(&minpath);

        // PrintMaze(maze, N, M);
        PT entry = {0, 0};
        GetMazePath(maze, N, M, entry, P);

        if(!STEmpty(&minpath)){
            PrintPath(&minpath);
        }else{
            printf("Can not escape!\n");
        }

        STDestroy(&path);
        STDestroy(&minpath);

        for (int i = 0; i < N; i++) {
            free(maze[i]);
            maze[i] = NULL;
        }
        free(maze);
        maze = NULL;
    }

    return 0;
}

